package com.wdciti.sccp.iot.position.model;

import com.wdciti.sccp.iot.tsdata.core.model.DataType;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;

import java.util.Arrays;
import java.util.List;

@Getter
public class MeasureDataValue {

    private final long timeStamp;
    private final String key;
    private Object value;
    @Setter
    private DataType dataType = DataType.TEXT; //默认String

    public MeasureDataValue(long timeStamp, @NonNull String key) {
        this.timeStamp = timeStamp;
        this.key = key;
    }

    public MeasureDataValue(long timeStamp, @NonNull String key, @NonNull DataType dataType) {
        this.timeStamp = timeStamp;
        this.key = key;
        this.dataType = dataType;
    }

    public MeasureDataValue(long timeStamp, @NonNull String key, @NonNull Object value) {
        this.timeStamp = timeStamp;
        this.key = key;
        this.value = value;
        this.dataType = judgeType(value);
    }

    public MeasureDataValue(long timeStamp, @NonNull String key, @NonNull Object value, @NonNull DataType dataType) {
        this.timeStamp = timeStamp;
        this.key = key;
        this.dataType = dataType;
        this.value = value;
    }

    public void setStrValue(String value){
        if(value != null){
            this.value = packageValue(value);
        }
    }

    public MeasureDataValue setObjValueAndJudgeType(Object value){
        if (value != null) {
            this.value = value;
            this.dataType = judgeType(value);
        }
        return this;
    }

    public MeasureDataValue setValue(@NonNull Object value, @NonNull DataType type){
        this.value = value;
        this.dataType = type;
        return this;
    }

    private Object packageValue(String value) {
        switch (this.dataType) {
            case BOOLEAN:
                return Boolean.valueOf(value);
            case INT32:
                return Integer.valueOf(value);
            case INT64:
                return Long.valueOf(value);
            case FLOAT:
                return Float.valueOf(value);
            case DOUBLE:
                return Double.valueOf(value);
            case TEXT:
                return value;
//            case VECTOR:
//                return Arrays;    //TODO:暂不支持数组，后续用json
            default:
                throw new IllegalArgumentException("Invalid input: " + this.dataType);
        }
    }

    private <T> List<T> packageValue(T[] arrayValues) {
        return Arrays.asList(arrayValues);
    }


    private DataType judgeType(Object value) {
        if (value == null) {
            return DataType.TEXT;
        }
        if (value instanceof Boolean) {
            return DataType.BOOLEAN;
        } else if (value instanceof Integer) {
            return DataType.INT32;
        } else if (value instanceof Long) {
            return DataType.INT64;
        } else if (value instanceof Float) {
            return DataType.FLOAT;
        } else if (value instanceof Double) {
            return DataType.DOUBLE;
        } else if (value instanceof String) {
            return DataType.TEXT;
        } else if (value instanceof List) {
            return DataType.VECTOR;
        } else {
            throw new IllegalArgumentException("Invalid input: " + value.getClass());
        }
    }
}
